﻿using System.Collections.Generic;

namespace DL.AI.AIGOAP
{
    //代理行为
    public class AgentAction
    {
        public string Name { get; }

        //成本
        public float Cost { private set; get; }

        //先决条件
        public HashSet<AgentBelief> Preconditions { get; } = new();
        //完成行为后的影响
        public HashSet<AgentBelief> Effects { get; } = new();

        AgentAction(string name)
        {
            Name = name;
        }

        private IActionStrategy m_Strategy;


        public bool CanPerform() => m_Strategy.CanPerform();

        public bool Complete() => m_Strategy.Complete();
        
        public void Start() => m_Strategy.Start();

        public void Update(float deltaTime)
        {
            if (CanPerform())
            {
                m_Strategy.Update(deltaTime);
            }
            
            if (!Complete())return;
          
            //如果完成了
            //计算所有影响
            foreach (var effect in Effects)
            {
                effect.Evaluate();
            }
            
            
        }

        public void Stop()=> m_Strategy.Stop();
        
        public class Builder
        {
            private readonly AgentAction m_AgentAction;

            public Builder(string name)
            {
                m_AgentAction = new(name)
                {
                    Cost = 1
                };
            }

            public Builder WithCost(float cost)
            {
                m_AgentAction.Cost = cost;
                return this;
            }
            
            public Builder WithStrategy(IActionStrategy strategy)
            {
                m_AgentAction.m_Strategy = strategy;
                return this;
            }
            
            public Builder WithPrecondition(AgentBelief precondition)
            {
                m_AgentAction.Preconditions.Add(precondition);
                return this;
            }
            
            public Builder WithEffect(AgentBelief effect)
            {
                m_AgentAction.Effects.Add(effect);
                return this;
            }

            public AgentAction Build() => m_AgentAction;

        }
        
    }
}